package io.mft.yapi.util;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONNull;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import io.mft.commons.config.ConfigProvider;
import io.mft.commons.exception.MFTException;
import io.mft.commons.function.response.kv.KVMap;

public class RequestParam {
	private static String URL = "http://" + ConfigProvider.getHostProgramConfigValue("yApi.ip", "10.0.209.216");

	// private static String
	// TOKEN=ConfigProvider.get("yApi.token","7ac48909ba99abcd1f31764d98baedd59de93146d2782fc6435412ea321b34d1");
//    private static String PROJECT_ID = "9";
//    private static String GROUP_ID = "13";
	private RequestParam() {
	}

	private static RequestParam instance = new RequestParam();

	public static RequestParam getInstance() {
		return instance;
	}

	private Logger logger = LoggerFactory.getLogger(RequestParam.class);

	public String queryProject(String token) {
		String id = "";
		Map<String, Object> paramMap = new HashMap<>();
		paramMap.put("token", token);
		String url = URL + "/api/project/get";
		String json = HttpUtil.get(url, paramMap);

		JSONObject jsonObject = JSONUtil.parseObj(json);
		// System.out.println(JSON.toJSONString(jsonObject, true));
		if (jsonObject.getInt("errcode") == 0) {
			JSONObject data = jsonObject.getJSONObject("data");
			if (data != null) {
				id = data.getStr("_id");
			}
		}
		if (ObjectUtil.isEmpty(id)) {
			throw new MFTException("查询项目[" + token + "]的ID为空，请检查！");
		}
		return jsonObject.getJSONObject("data").toString();
	}

	public HttpPost setReqHeader(String url) {

		HttpPost postMethod;
		postMethod = new HttpPost(url);

		postMethod.addHeader("Content-type", "application/json; charset=utf-8");
		postMethod.addHeader("Accept", "application/json");
		postMethod.addHeader("Accept-Encoding", "gzip,deflate");
		postMethod.addHeader("Connection", "keep-alive");
		postMethod.addHeader("Accept-Language", "zh-CN");
		postMethod.addHeader("Host", ConfigProvider.get("yApi.ip", "10.0.209.216"));
		postMethod.addHeader("Origin", URL);
		postMethod.addHeader("Referer", URL + "login");
		postMethod.addHeader("User-Agent",
				"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36");

		return postMethod;
	}

	public String getCookie() {
		Map<String, Object> paramMap = new HashMap<>();
		KVMap kv = YApiAccount.get();
		paramMap.put("email", kv.get("yApi.YApiLoginEmail", ""));
		paramMap.put("password", kv.get("yApi.YApiPassword", ""));
		// System.out.println(paramMap);
		JSONObject data = new JSONObject();
		data.putAll(paramMap);
		String url = URL + "/api/user/login";
		String cookie = "";

		HttpClient httpClient;
		HttpResponse response;
		httpClient = HttpClients.createDefault();

		try {
			HttpPost postMethod = setReqHeader(url);
			postMethod.setEntity(new StringEntity(String.valueOf(data), Charset.forName("utf-8")));
			response = httpClient.execute(postMethod);
			List headers = Arrays.asList(response.getHeaders("Set-Cookie"));
			String cookie_1 = (headers.get(0).toString().split("Set-Cookie:"))[1].split(";")[0];
			String cookie_2 = (headers.get(1).toString().split("Set-Cookie:"))[1].split(";")[0];
			cookie = cookie_1 + ";" + cookie_2;
		} catch (Exception e) {
			logger.error("", e);
			throw new MFTException("YAPI登陆账户或密码错误!");
		}finally {
		}

		return cookie;
	}

	public void getGroupList(String token) {
		Map<String, Object> paramMap = new HashMap<>();
		paramMap.put("token", token);
		paramMap.put("id", getGroupId(token));
		String url = URL + "/api/group/get";
		String json = HttpUtil.get(url, paramMap);
		JSONObject jsonObject = JSONUtil.parseObj(json);
		// System.out.println(JSON.toJSONString(jsonObject, true));
	}

	public String getCategoryMenu(String token) {
		Map<String, Object> paramMap = new HashMap<>();
		paramMap.put("token", token);
		//paramMap.put("id", getGroupId(token));
		paramMap.put("project_id", getProjectId(token));
		
		String url = URL + "/api/interface/getCatMenu";
		String json = HttpUtil.get(url, paramMap);
//        JSONObject jsonObject=JSONUtil.parseObj(json);
//        System.out.println(JSON.toJSONString(jsonObject, true));
		return json;

	}

	public String getInterfaceDetail(String token, String interfaceName) {
		Map<String, Object> paramMap = new HashMap<>();
		String url = URL + "/api/interface/get";
		// paramMap.put("id","290");
		paramMap.put("id", getInterfaceId(token, interfaceName));
		// paramMap.put("token",TOKEN);
		String result = HttpRequest.get(url).contentType("application/json").form(paramMap).execute().body();

		JSONObject jsonObject = JSONUtil.parseObj(result);
		return jsonObject.getStr("data");
	}

	public String getInterfaceList(String token) {
		Map<String, Object> paramMap = new HashMap<>();
		String url = URL + "/api/interface/list";
		paramMap.put("project_id", getProjectId(token));
		paramMap.put("token", token);
//        paramMap.put("page","1");
        paramMap.put("limit",Integer.MAX_VALUE);
		String result = HttpRequest.get(url).contentType("application/json").form(paramMap).execute().body();
		JSONObject jsonObject = JSONUtil.parseObj(result);
//        System.out.println(JSON.toJSONString(jsonObject, true));
		return jsonObject.getStr("data");
	}

	public void getInterfaceListMenu(String token) {
		Map<String, Object> paramMap = new HashMap<>();
		String url = URL + "/api/interface/list_menu";
		paramMap.put("project_id", getGroupId(token));
		paramMap.put("token", token);
		paramMap.put("page", "1");
		paramMap.put("limit", "10");
		String result = HttpRequest.get(url).contentType("application/json").form(paramMap).execute().body();
		JSONObject jsonObject = JSONUtil.parseObj(result);
		// System.out.println(JSON.toJSONString(jsonObject, true));
	}

	public String getProjectId(String token) {
		JSONObject data = new JSONObject(queryProject(token));
		String project_id = data.getStr("_id");
		return project_id;
	}

	public String getGroupId(String token) {
		JSONObject data = new JSONObject(queryProject(token));
		String group_id = data.getStr("group_id");
		return group_id;
	}
	public String getCatId(String token, String CategoryName) {
		JSONObject jsonObject = JSONUtil.parseObj(getCategoryMenu(token));
		JSONArray data = new JSONArray((jsonObject.get("data")));
		String catId = "";
		for (Object item : data) {
			String catName = ((JSONObject) item).getStr("name");
			if (catName.equals(CategoryName)) {
				catId = ((JSONObject) item).getStr("_id");
			}
		}
		if ("".equals(catId)) {
			logger.error("\"" + CategoryName + "\"项目分类不存在!");
		}
		return catId;
	}

	public String getInterfaceId(String token, String InterfaceName) {
		String data = RequestParam.getInstance().getInterfaceList(token);
		JSONObject jsonObject = JSONUtil.parseObj(data);
		JSONArray list = new JSONArray((jsonObject.get("list")));
//        System.out.println("list:"+JSON.toJSONString(list));
		String interfaceId = "";
		for (Object item : list) {
			String interName = ((JSONObject) item).getStr("title");
			if (interName.equals(InterfaceName)) {
				interfaceId = ((JSONObject) item).getStr("_id");
			}
		}
		if ("".equals(interfaceId)) {
			logger.error("\"" + InterfaceName + "\"接口不存在!");
		}
		return interfaceId;
	}

	public String getPath(String FuncNo) {
		return "/" + FuncNo;
	}

	public List<String> getParamName(String token, String interfaceName) {
		List nameQuery = new ArrayList();
		String data = RequestParam.getInstance().getInterfaceDetail(token, interfaceName);
		JSONObject jsonObject = JSONUtil.parseObj(data);
		JSONArray list = new JSONArray(jsonObject.get("req_query"));
		for (Object item : list) {
			String name = ((JSONObject) item).getStr("name");
			nameQuery.add(name);
		}
		return nameQuery;
	}

	public JSONObject addInterfaceReqParam(String name, String description, boolean required, String example) {

		Map reqParam = new HashMap();
		JSONObject jsonObject = new JSONObject();

		reqParam.put("desc", description);
		reqParam.put("example", example);
		reqParam.put("required", required ? 1 : 0);
		reqParam.put("name", name);
		jsonObject.putAll(reqParam);

		return jsonObject;
	}

	public List<Object> setRequestQuery(List<YApiMetaParser.YApiAttributeMeta> interfaceParams) {
		List reqQuery = new ArrayList();
		for (YApiMetaParser.YApiAttributeMeta reqParam : interfaceParams) {
			JSONObject reqQuery_jsonObject = addInterfaceReqParam(reqParam.name, reqParam.note, reqParam.requried,
					reqParam.example);
			reqQuery.add(reqQuery_jsonObject);
		}
		return reqQuery;
	}

	public String setResponseBody(Map<String, List<YApiMetaParser.YApiAttributeMeta>> outYApiAttributeMetasMap) {
		// System.out.println("设置返回参数...");
		Map properties = new HashMap();
		Map resultParam = new HashMap();
		List required = new ArrayList();
		Map itemType = new HashMap();
		itemType.put("type", "string");

		JSONObject data = new JSONObject();

		resultParam.put("$schema", "http://json-schema.org/draft-04/schema#");
		resultParam.put("type", "object");

		Map error_msg = new HashMap();
		error_msg.put("type", "string");
		error_msg.put("description", "错误信息");
		Map error_mock = new HashMap();
		error_mock.put("mock", "调用成功");
		error_msg.put("mock", error_mock);

		Map dsName = new HashMap<>();
		dsName.put("type", "array");
		dsName.put("items", itemType);
		dsName.put("description", "结果集名称");
		Map dsName_mock = new HashMap();
		List dsName_item = new ArrayList();

		Map errorNo = new HashMap();
		errorNo.put("type", "string");
		Map errorNo_mock = new HashMap();
		errorNo_mock.put("mock", "0");
		errorNo.put("mock", errorNo_mock);

		required.add("error_info");
		required.add("dsName");

		properties.put("error_info", error_msg);
		properties.put("dsName", dsName);
		properties.put("error_no", errorNo);
		required.add("error_no");
		// 分析不为空的情况
		if (!outYApiAttributeMetasMap.isEmpty()) {
			for (Map.Entry<String, List<YApiMetaParser.YApiAttributeMeta>> entry : outYApiAttributeMetasMap
					.entrySet()) {
				Map resultsName = new HashMap();
				String resName = entry.getKey();
				resultsName.put("type", "array");
				resultsName.put("description", entry.getKey());

				Map items = new HashMap();
				items.put("type", "object");
				Map item_properties = new HashMap();
				List item_required = new ArrayList();
				for (YApiMetaParser.YApiAttributeMeta outParam : entry.getValue()) {
					Map out = new HashMap();
					Map mock = new HashMap();
					mock.put("mock", outParam.example);
					out.put("type", "string");
					out.put("description", outParam.note);
					out.put("mock", mock);
					item_properties.put(outParam.name, out);
					if (outParam.requried) {
						item_required.add(outParam.name);
					}
				}
				items.put("properties", item_properties);
				items.put("required", item_required);
				resultsName.put("items", items);
				properties.put(resName, resultsName);
				required.add(resName);
				dsName_item.add(resName);
			}
			resultParam.put("required", required);
		}
		dsName_mock.put("mock", dsName_item);
		dsName.put("mock", dsName_mock);

		resultParam.put("properties", properties);
		data.putAll(resultParam);
		// System.out.println(data);

		return String.valueOf(data);
	}

	public String setMockRequestBody(Map<String, List<YApiMetaParser.YApiAttributeMeta>> outYApiAttributeMetasMap) {
		Map reqBody = new HashMap();
		JSONObject data = new JSONObject();

		List dsName_list = new ArrayList();
		reqBody.put("error_info", "");
		reqBody.put("error_no", "0");

		if (!outYApiAttributeMetasMap.isEmpty()) {
			for (Map.Entry<String, List<YApiMetaParser.YApiAttributeMeta>> entry : outYApiAttributeMetasMap
					.entrySet()) {
				Map result_map = new HashMap();
				List result_list = new ArrayList();
				for (YApiMetaParser.YApiAttributeMeta outParam : entry.getValue()) {
					result_map.put(outParam.name, outParam.example);
				}
				JSONObject result_jo = new JSONObject();
				result_jo.putAll(result_map);
				result_list.add(result_jo);
				reqBody.put(entry.getKey(), result_list);
				dsName_list.add(entry.getKey());
			}
		}
		reqBody.put("dsName", dsName_list);
		data.putAll(reqBody);
		return String.valueOf(data);
	}

	public List getMockList(String token, String interfaceName) throws IOException {
		String interfaceId = getInterfaceId(token, interfaceName);
		String url = URL + "/api/plugin/advmock/case/list?interface_id=" + interfaceId;
		List data = new ArrayList();

		HttpClient httpClient;
		HttpGet postMethod;
		HttpResponse response;
		String reponseContent;
		httpClient = HttpClients.createDefault();
		postMethod = new HttpGet(url);

		postMethod.addHeader("Content-type", "application/json; charset=utf-8");
		postMethod.addHeader("Accept", "application/json");
		postMethod.addHeader("Accept-Encoding", "gzip,deflate");
		postMethod.addHeader("Connection", "keep-alive");
		postMethod.addHeader("Accept-Language", "zh-CN");
		postMethod.addHeader("Host", "10.0.209.216");
		postMethod.addHeader("Origin", "http://10.0.209.216");
		postMethod.addHeader("Referer", "http://10.0.209.216/login");
		postMethod.addHeader("User-Agent",
				"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36");
		postMethod.addHeader("cookie", getCookie());

		response = httpClient.execute(postMethod);
		HttpEntity httpEntity = response.getEntity();
		reponseContent = EntityUtils.toString(httpEntity);
		JSONObject jsonObject = JSONUtil.parseObj(reponseContent);
		if (jsonObject.get("data")==null||jsonObject.get("data") instanceof JSONNull) {
			return null;
		}
		data = (List) jsonObject.get("data");
//        System.out.println(JSON.toJSONString(jsonObject,SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue,
//                SerializerFeature.WriteDateUseDateFormat));
		return data;
	}

	public boolean checkMockList(String token, String interfaceName) throws IOException {
		boolean flag = false;
		List data = getMockList(token, interfaceName);
		if (data==null) {
			return flag;
		}
		for (Object d : data) {
			String name = ((JSONObject) d).getStr("name");
			if (!name.equals("")) {
				flag = true;
			}
		}
		return flag;
	}

	public void delMockCase(String token, String interfaceName) throws IOException {
		Map<String, Object> paramMap = new HashMap<>();

		List dataList = getMockList(token, interfaceName);
		if (dataList==null) {
			return ;
		}
		String id = ((JSONObject) dataList.get(0)).getStr("_id");
		paramMap.put("id", String.valueOf(id));
		JSONObject data = new JSONObject();
		data.putAll(paramMap);
		String url = URL + "/api/plugin/advmock/case/del";

		HttpClient httpClient;
		HttpResponse response;
		httpClient = HttpClients.createDefault();

		try {
			HttpPost postMethod = setReqHeader(url);
			postMethod.addHeader("cookie", getCookie());
			postMethod.setEntity(new StringEntity(String.valueOf(data), Charset.forName("utf-8")));
			response = httpClient.execute(postMethod);
			if (JSONUtil.parseObj(EntityUtils.toString(response.getEntity())).getStr("errcode").equals("0")) {
				logger.info("删除Mock期望成功！");
			} else {
				logger.error("删除Mock期望失败！");
			}

		} catch (Exception e) {
			logger.error("", e);
		}

	}

	public static void main(String[] args) throws IOException {
		RequestParam requestParam = new RequestParam();
		// requestParam.getMockList();
		// System.out.println(Configuration.getItems());

	}
}
